const loginApi = require("../persistent_api/loginApi");

const validate = require("../middleware/validate");
const ResponseMessage = require("../response/message");

const md5 = require("md5")

const log4js = require("log4js");
const logger = log4js.getLogger();

const { body , query } = require("express-validator");

/**
 * 验证登录参数
 * @param {Request} req 
 * @param {Response} res 
 * @param {Function} next 
 */
exports.loginParamsValidator = (req, res, next) => {
  if (JSON.stringify(req.body) === "{}") {
    logger.warn(req.ip + " - " + req.method + " - " + req.originalUrl + " - 缺失请求体")
    res.send(new ResponseMessage(400, "缺失请求体", {}));
  } else {
    // 登录类型
    const loginType = req.body.loginType;
    if (!req.body.loginType) {
      logger.warn(req.ip + " - " + req.method + " - " + req.originalUrl + " - 缺少 loginType 参数")
      res.send(new ResponseMessage(400, "缺少 loginType 参数", {}));
    } else {
      let paramsAuthArr = [];
      try{
        switch (loginType) {
          case 1:
            paramsAuthArr = [
              body("studentNo").notEmpty().withMessage("学号不能为空"),
              body("studentName").notEmpty().withMessage("学生姓名不能为空"),
            ];
            break;
          case  2:
            paramsAuthArr = [
              body("teacherNo").notEmpty().withMessage("工号不能为空"),
              body("teacherName").notEmpty().withMessage("教师姓名不能为空"),
            ];
            break;
          case 3:
            paramsAuthArr = [
              body("deanNo").notEmpty().withMessage("工号不能为空"),
              body("deanName").notEmpty().withMessage("院长姓名不能为空"),
            ];
            break;
          case  4:
            paramsAuthArr = [
              body("name").notEmpty().withMessage("用户名不能为空"),
              body("pwd").notEmpty().withMessage("密码不能为空"),
            ];
            break;
          default:
            logger.warn(req.ip + " - " + req.method + " - " + req.originalUrl + " - 未知的登录类型")
            return res.status(201).send(new ResponseMessage(201, "未知的登录类型", {}));
        }
      }catch(error){
          logger.error(req.ip + " - " + req.method + " - " + req.originalUrl + " - " + error.message)
          return res.status(500).send(new ResponseMessage(500, "网络错误", {}));
      }
      // 验证
      validate(paramsAuthArr)(req, res, next);
    }
  }
};

/**
 * 
 * @param {Request} req 
 * @param {*} res 
 * @param {*} next 
 */
exports.loginUserExistsValidator = (req, res, next) => {
  const { loginType } = req.body;
  const body = req.body;
  // 使用一个自调用函数 设置为 async 函数 同时实参封装一个通用的处理函数
  (async (type,commonHandler) => {
      req.loginType = type;
      try{
        switch (+type) {  
          case 1:
            const studentInfo = await loginApi.studentIsLogin(body.studentNo,body.studentName);
            if(commonHandler({
                req,
                res,
                entity:studentInfo,
                codes:[201,201],
                msgs:["未找到学生信息,或用户名或密码错误","该学生账号已在其他地方登录,请退出后在尝试"],
            })){
              await loginApi.updateStudentLoginStatus(body.studentNo,body.studentName,1);
              next();
            };
            break; 
          case 2:
            const teacherInfo = await loginApi.teacherIsLogin(body.teacherNo,body.teacherName);
            if(commonHandler({
                req,
                res,
                entity:teacherInfo,
                codes:[201,201],
                msgs:["未找到教师信息,或用户名或密码错误","该教师账号已在其他地方登录,请退出后在尝试"],
            })){
              await loginApi.updateTeacherLoginStatus(body.teacherNo,body.teacherName,1);
              next()
            };
            break;
           case 3:
            const deanInfo = await loginApi.deanIsLogin(body.deanNo,body.deanName);
            if(commonHandler({
                req,
                res,
                entity:deanInfo,
                codes:[201,201],
                msgs:["未找到院长信息,或用户名或密码错误","该院长账号已在其他地方登录,请退出后在尝试"],
            })){
              await loginApi.updateDeanLoginStatus(body.deanNo,body.deanName,1);
              next()
            };
            break; 
           case 4:
            const adminInfo = await loginApi.adminIsLogin(body.name,md5(body.pwd));
            if(commonHandler({
                req,
                res,
                entity:adminInfo,
                codes:[201,201],
                msgs:["未找到校长信息,或用户名或密码错误","该校长账号已在其他地方登录,请退出后在尝试"],
            })){
              await loginApi.updateAdminLoginStatus(body.name,md5(body.pwd),1);
              next()
            };  
            break;
          default: 
            logger.error(req.ip + " - " + req.method + " - " + req.originalUrl + " - 未找到相关账户信息")
            return res.status(201).send(new ResponseMessage(201, "未找到相关账户信息", {}));  
        }
      }catch(error){
         logger.error(req.ip + " - " + req.method + " - " + req.url + " - 网络错误")
         return res.send(new ResponseMessage(500,"网络错误",{}))
      }
  })(loginType,(options)=>{
    if (!options.entity)   {
      logger.warn(req.ip + " - " + req.method + " - " + req.originalUrl + " - "+options.msgs[0])
      return options.res.status(201).send(new ResponseMessage(options.codes[0], options.msgs[0] , options.data || {})) && false;
    }
    else {
        logger.warn(req.ip + " - " + req.method + " - " + req.originalUrl + " - "+options.msgs[1])
        if(options.entity.loginStatus !== 0) return  options.res.status(201).send(new ResponseMessage(options.codes[1], options.msgs[1] , options.data || {})) && false;
        else return (options.req.userInfo = options.entity) && true;
    } 
  });
};

/**
 * 验证认证时需要传递的参数
 * @param {Request} req 
 * @param {Response} res 
 * @param {Function} next 
 */
exports.loginAuthParamsValidator = (req,res,next) => {
  if (JSON.stringify(req.body) === "{}") {
    res.send(new ResponseMessage(400, "缺失请求体", {}));
  } else {
      // 验证
      validate([
        body("id").notEmpty().withMessage("登录用户的ID不能为空"),
        body("loginType").notEmpty().withMessage("登录类型不能为空"),
      ])(req, res, next);
    }
} 

exports.logoutParamsValidator = (req,res,next) => {
  if (JSON.stringify(req.query) === "{}") {
    logger.warn(req.ip + " - " + req.method + " - " + req.originalUrl + " - 缺失查询字符串参数")
    res.send(new ResponseMessage(400, "缺失查询字符串参数", {}));
  } else {
      // 验证
      validate([
        query("id").notEmpty().withMessage("退出用户的ID不能为空"),
        query("loginType").notEmpty().withMessage("用户的登录类型不能为空"),
      ])(req, res, next);
    }
}